/**
 * Copyright (c) 2009, 2012 Robert Bosch GmbH and its subsidiaries.
 * This program and the accompanying materials are made available under
 * the terms of the Bosch Internal Open Source License v3.3
 * which accompanies this distribution, and is available at
 * http://bios.intranet.bosch.com/fusionx/BIOSL33-License.txt
 */
package productserver.views;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.TreeColumn;

/**
 * Sorter to sort columns in EMS Properties view.
 * 
 *  @author Velganesh
 */
public abstract class ColumnSorter extends ViewerComparator {

	private ColumnViewer columnViewer = null;
	private TreeColumn column = null;
	private int direction = SWT.DOWN;
	private int columnIndex = 0;

	/**
	 * Creates an instance of {@code ColumnSorter}.
	 * 
	 * @param columnViewer
	 *            the viewer to which the column belongs to
	 * @param column
	 *            the column to which this sorter is applicable
	 */
	public ColumnSorter(final ColumnViewer columnViewer, TreeColumn column) {
		Assert.isNotNull(columnViewer, "columnViewer");
		Assert.isNotNull(column, "column");

		this.columnViewer = columnViewer;
		this.column = column;
		this.columnIndex = getColumnIndex();
		this.column.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				if (ColumnSorter.this.columnViewer.getComparator() != ColumnSorter.this) {
					setDirection(SWT.DOWN);
				} else {
					int sortDirection = ColumnSorter.this.column.getParent()
							.getSortDirection();
					if (sortDirection == SWT.NONE) {
						setDirection(SWT.DOWN);
					} else {
						setDirection(sortDirection == SWT.UP ? SWT.DOWN : SWT.UP);
					}
				}
			}
		});

	}

	/**
	 * Returns the text of the object that should be used in the column
	 * specified by the index.
	 * 
	 * @param obj
	 *            the source object
	 * @param columnIndexForText
	 *            index of column for which text is needed
	 * @return the text applicable for the column, or {@code null}
	 */
	public abstract String getColumnText(Object obj, int columnIndexForText);

	/**
	 * Sets the sorting direction.
	 * 
	 * @param newDirection
	 */
	public final void setDirection(final int newDirection) {
		column.getParent().setSortColumn(column);
		this.direction = newDirection;
		column.getParent().setSortDirection(this.direction);
		if (this.columnViewer.getComparator() == this) {
			this.columnViewer.refresh(false);
		} else {
			this.columnViewer.setComparator(this);
		}
	}

	/** {@inheritDoc}
	 * @see org.eclipse.jface.viewers.ViewerComparator
	 * #compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	public final int compare(final Viewer viewer, final Object e1, final Object e2) {
		String text1 = getColumnText(e1, columnIndex);
		if (text1 == null) {
			text1 = "";
		}
		String text2 = getColumnText(e2, columnIndex);
		if (text2 == null) {
			text2 = "";
		}
		return (direction == SWT.UP ? 1 : -1) * text1.compareTo(text2);
	}

	/**
	 * Returns the index of the given column in the parent table.
	 * 
	 * @return index of the column in the parent table, or zero if the parent
	 *         table does not have this column
	 */
	private int getColumnIndex() {
		int idx = this.column.getParent().indexOf(this.column);
		return (idx < 0 ? 0 : idx);
	}
}
